home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Test / ConSerIO / Console.c < prev    next >
C/C++ Source or Header  |  1996-06-25  |  11KB  |  372 lines

  1. /* Incredibly Basic Terminal Program (C) 1995 Hydra/Tension
  2.  
  3.    Part of the development for HBBS!
  4.  
  5.    This program demonstrates async serial.device and console.device IO
  6.    with a 0 cpu usage wait.
  7.  
  8.    Note: it took me ages to get this working as when you get data from the serial
  9.    port and write it to the console device you sometimes get a signal from the
  10.    console device saying that some data is there, only when you got to waitio() the
  11.    request it just sat there!  not good.  so the trick when using wait() and signals
  12.    is to SetSignal(yoursig,0L) *BEFORE* you do another SendIO() on the console or
  13.    serial device.. then you don't get that weird signal without io problem!
  14.  
  15.    Weird huh ?  now it NEVER says anything about this in ANY manuals ANYWHERE at
  16.    all not even in the RKM's! and is serious hairpulling stuff!!
  17.  
  18.    this source code is freeware, use it in your programs, cut and paste bits and
  19.    do whatever you like with it, I thought I'd release it into the public domain
  20.    as it seems that alot of other people have had problems reading and writing
  21.    to serial ports too..
  22.  
  23.    If you use this source code or bits of it or take ideas from it then PLEASE
  24.    mention my name somewhere in your docs for your program!
  25.  
  26. */
  27.  
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33.  
  34. #include <exec/exec.h>
  35. #include <intuition/intuition.h>
  36. #include <devices/console.h>
  37. #include <devices/serial.h>
  38. #include <dos/dos.h>
  39. #include <libraries/reqtools.h>
  40.  
  41. #include <clib/exec_protos.h>
  42. #include <clib/alib_protos.h>
  43. #include <clib/intuition_protos.h>
  44. #include <clib/console_protos.h>
  45. #include <clib/dos_protos.h>
  46. #include <clib/reqtools_protos.h>
  47.  
  48. #define ClrSignal(s)  SetSignal(0,s)
  49.  
  50. extern struct GfxBase *GfxBase;
  51. extern struct IntuitionBase *IntuitionBase;
  52. struct ReqToolsBase *ReqToolsBase;
  53. struct Window *Win=NULL;
  54. struct Screen *Scr=NULL;
  55.  
  56. struct IOStdReq *ConRead;
  57. struct IOStdReq *ConWrite;
  58. struct MsgPort *ConRPort;
  59. struct MsgPort *ConWPort;
  60.  
  61. struct IOExtSer *SerRead;
  62. struct IOExtSer *SerWrite;
  63. struct MsgPort *SerPort;
  64. //struct MsgPort *SerReadPort;
  65.  
  66. long __stack = 40000;
  67.  
  68.   char ConBuffer[2048];
  69.   char SerBuffer[2048];
  70.   char SerialInChar;
  71.   ULONG SerBufLen;
  72.  
  73. BOOL SerFlag=FALSE;
  74. BOOL ConFlag=FALSE;
  75.  
  76. void CloseLibs( void )
  77. {
  78. if (NULL != GfxBase )
  79.   CloseLibrary( ( struct Library * )GfxBase );
  80. if (NULL != IntuitionBase )
  81.   CloseLibrary( ( struct Library * )IntuitionBase );
  82.   if (ReqToolsBase)
  83.     CloseLibrary ((struct Library *)ReqToolsBase);
  84.   exit (0);
  85. }
  86.  
  87. int OpenLibs( void )
  88. {
  89.   if (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION))
  90.     if ( NULL != (GfxBase = (struct GfxBase * )OpenLibrary((UBYTE *)"graphics.library" , 37)))
  91.       if ( NULL != (IntuitionBase = (struct IntuitionBase * )OpenLibrary((UBYTE *)"intuition.library" , 37)))
  92.     return( 0L );
  93.   CloseLibs();
  94. return( 1L );
  95. }
  96.  
  97. BYTE OpenConsole(struct IOStdReq *writereq, struct IOStdReq *readreq, struct Window *window)
  98. {
  99.   BYTE error;
  100.  
  101.   // point to window..
  102.  
  103.   writereq->io_Data = (APTR) window;
  104.   writereq->io_Length = sizeof(struct Window);
  105.  
  106.   // open device..
  107.  
  108.   error = OpenDevice("console.device", 0, (struct IORequest*)writereq, 0);
  109.  
  110.   // duplicate data..
  111.  
  112.   readreq->io_Device = writereq->io_Device; /* clone required parts */
  113.   readreq->io_Unit   = writereq->io_Unit;
  114.  
  115.   return(error);
  116. }
  117.  
  118. void cancelcon( void )
  119. {
  120.   if (ConFlag)
  121.   {
  122.     AbortIO((struct IORequest *)ConRead);
  123.     WaitIO((struct IORequest *)ConRead);
  124.     ConFlag=FALSE;
  125.   }
  126. }
  127.  
  128. void readcon( void )
  129. {
  130.   if (!ConFlag)
  131.   {
  132.     ConRead->io_Command  = CMD_READ;
  133.     ConRead->io_Data     = (APTR)ConBuffer;
  134.     ConRead->io_Length   = 1;
  135.     ClrSignal(1L << ConRPort->mp_SigBit);
  136.     SendIO((struct IORequest*)ConRead);
  137.     ConFlag=TRUE;
  138.   }
  139. }
  140.  
  141. void ConWriteData(UBYTE *data,ULONG length)
  142. {
  143.   cancelcon();
  144.   ConWrite->io_Command  = CMD_WRITE;
  145.   ConWrite->io_Data     = data;
  146.   ConWrite->io_Length   = length;
  147.  
  148.   DoIO((struct IORequest *)ConWrite);
  149.   readcon();
  150. }
  151.  
  152. void cancelser( void )
  153. {
  154.   if (SerFlag)
  155.   {
  156.     AbortIO((struct IORequest *)SerRead);
  157.     WaitIO((struct IORequest *)SerRead);
  158.     SerFlag=FALSE;
  159.   }
  160. }
  161.  
  162. void readser( void )
  163. {
  164.  
  165.   if (!SerFlag)
  166.   {
  167.     SerRead->IOSer.io_Command  = CMD_READ;
  168.     SerRead->IOSer.io_Data     = &SerialInChar;
  169.     SerRead->IOSer.io_Length   = 1;
  170.     ClrSignal(1L << SerPort->mp_SigBit);
  171.     SendIO((struct IORequest*)SerRead);
  172.     SerFlag=TRUE;
  173.   }
  174. }
  175.  
  176. void SerWriteData(UBYTE *data,ULONG length)
  177. {
  178.   cancelser();
  179.   SerWrite->IOSer.io_Command  = CMD_WRITE;
  180.   SerWrite->IOSer.io_Data     = data;
  181.   SerWrite->IOSer.io_Length   = length;
  182.  
  183.   DoIO((struct IORequest *)SerWrite);
  184. }
  185.  
  186. void HandleIt( void )
  187. {
  188.   struct IntuiMessage *IMsg;
  189.   BOOL done=FALSE;
  190.   ULONG SerSigs,ConSigs,WinSigs,ReturnedSigs;
  191.  
  192.  
  193.   while (!done)
  194.   {
  195.     if (!SerFlag) readser();
  196.     if (!ConFlag) readcon();
  197.  
  198.     ConSigs=ConFlag ? 1L << ConRPort->mp_SigBit : 0;
  199.     SerSigs=SerFlag ? 1L << SerPort->mp_SigBit : 0;
  200.     WinSigs=1L << Win->UserPort->mp_SigBit;
  201.  
  202.     // the sigbreak bit can ONLY be activated if another program sends a break
  203.     // to this program, something like artm or taske might be usefull! :-)
  204.     // you can't type ctrl-c cos the console.device gets there first!
  205.  
  206.  
  207.     // put the task to sleep until we get some input!
  208.  
  209.     ReturnedSigs=Wait(SerSigs | ConSigs | WinSigs | SIGBREAKF_CTRL_C);
  210.  
  211.     // check to see what input happened
  212.  
  213.     if (ReturnedSigs & SIGBREAKF_CTRL_C) done=TRUE;
  214.  
  215.     // something happened to the window..
  216.     if (ReturnedSigs & WinSigs)
  217.     {
  218.       while (IMsg=(struct IntuiMessage *)GetMsg(Win->UserPort))
  219.       {
  220.         switch (IMsg->Class)
  221.         {
  222.           case IDCMP_CLOSEWINDOW:
  223.             done=rtEZRequest("Quit ?","Yes|No",NULL,NULL,NULL);
  224.             break;
  225.         }
  226.         ReplyMsg((struct Message*)IMsg);
  227.       }
  228.     }
  229.     // if we have submitted a sendIO() to the console device check
  230.     // to see if a) the signal was from the console or b) check to see if the request
  231.     // has been completed,  this is usefull if you get a serial signal AND the
  232.     // computer was just about to send us a console signal..
  233.     if (ConFlag && ((ReturnedSigs & ConSigs) || CheckIO((struct IORequest *)ConRead)))
  234.     {
  235.       WaitIO((struct IORequest *)ConRead);
  236.       ConFlag=FALSE;
  237.       if (ConRead->io_Actual)
  238.       {
  239. // enable the following line if you want half duplex! :-)
  240. //      ConWriteData(ConBuffer,ConRead->io_Actual);
  241.         SerWriteData(ConBuffer,ConRead->io_Actual);
  242.       }
  243.     }
  244.  
  245.     // same as above except for serial instead of console..
  246.  
  247.     if (SerFlag && ((ReturnedSigs & SerSigs) || CheckIO((struct IORequest *)SerRead)))
  248.     {
  249.       // get the one byte of data we requested..
  250.       WaitIO((struct IORequest *)SerRead);
  251.       SerFlag=FALSE;
  252.       SerBuffer[0]=SerialInChar;
  253.       ConWriteData(SerBuffer,1); // and write it to the console..
  254.  
  255.       // then see if there's any more data to be read
  256.       // if there is write it to the console until there's no more left..
  257.       // nomally you might not want to do it like this as there is no way
  258.       // for the user to abort it!
  259.  
  260.       SerRead->IOSer.io_Command  = SDCMD_QUERY;
  261.       SerRead->IOSer.io_Actual = 0;
  262.       DoIO((struct IORequest*)SerRead);
  263.       do
  264.       {
  265.         // any data ?
  266.         if (SerRead->IOSer.io_Actual)
  267.         {
  268.           // yup! read it then!
  269.           SerRead->IOSer.io_Command  = CMD_READ;
  270.           SerRead->IOSer.io_Data     = &SerBuffer[0]; // be explicit, the [0] is not REALLY needed tho..
  271.                                        // don't forget not to overflow our buffer!
  272.           SerRead->IOSer.io_Length   = SerRead->IOSer.io_Actual>2048 ? 2048 : SerRead->IOSer.io_Actual ;
  273.           DoIO((struct IORequest*)SerRead);
  274.  
  275.           SerBufLen=SerRead->IOSer.io_Actual;
  276.           ConWriteData(SerBuffer,SerBufLen);
  277.         }
  278.         // send another query!
  279.         SerRead->IOSer.io_Command  = SDCMD_QUERY;
  280.         SerRead->IOSer.io_Actual = 0;
  281.         DoIO((struct IORequest*)SerRead);
  282.       }
  283.       while (SerRead->IOSer.io_Actual); // keep checking until no data exists..
  284.     }
  285.   }
  286.   // quit!
  287.   if (SerFlag) cancelser();
  288.   if (ConFlag) cancelcon();
  289. }
  290.  
  291.  
  292. void main(int argc, char *argv[])
  293. {
  294.   if (argc!=3)
  295.   {
  296.     puts("Usage: CONSOLE <device> <unit>");
  297.  
  298.   }
  299.   else
  300.   {
  301.     OpenLibs();
  302.  
  303.     if (Scr=LockPubScreen(NULL))
  304.     {
  305.  
  306.       if (Win=OpenWindowTags(NULL,
  307.                              WA_Width, 640,
  308.                              WA_Height, 256,
  309.                              WA_MaxWidth,65530,
  310.                              WA_MaxHeight,65530,
  311.                              WA_MinWidth,100,
  312.                              WA_MinHeight,100,
  313.                              WA_Title,"ASync Console.device and Serial.device By Hydra/TSN/LSD",
  314.                              WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_SIZEGADGET|WFLG_SIZEBRIGHT|WFLG_DEPTHGADGET,
  315.                              WA_IDCMP,IDCMP_CLOSEWINDOW,
  316.                              (TAG_DONE)))
  317.       {
  318.  
  319.         if (ConRPort=CreatePort(0,0))
  320.         {
  321.           if (ConWPort=CreatePort(0,0))
  322.           {
  323.             if(ConWrite = (struct IOStdReq *) CreateExtIO(ConWPort,(LONG)sizeof(struct IOStdReq)))
  324.             {
  325.               if(ConRead = (struct IOStdReq *) CreateExtIO(ConRPort,(LONG)sizeof(struct IOStdReq)))
  326.               {
  327.                 if(!(OpenConsole(ConWrite,ConRead,Win)))
  328.                 {
  329.                   if (SerPort=CreatePort(0,0) )
  330.                   {
  331.                     if (SerWrite=(struct IOExtSer *) CreateExtIO(SerPort,(ULONG)sizeof(struct IOExtSer)) )
  332.                     {
  333.                       SerWrite->io_SerFlags       = SERF_RAD_BOOGIE|SERF_XDISABLED|SERF_7WIRE|SERF_SHARED;
  334.                       if (!(OpenDevice(argv[1],atoi(argv[2]),(struct IORequest *)SerWrite,0) ))
  335.                       {
  336.                         SerWrite->IOSer.io_Command  = SDCMD_SETPARAMS;
  337.                         SerWrite->io_SerFlags       |= SERF_XDISABLED;
  338.                         SerWrite->io_Baud           = 19200;
  339.                         DoIO((struct IORequest *)SerWrite);
  340.  
  341.                         if (SerRead=(struct IOExtSer *) AllocMem(sizeof(struct IOExtSer),MEMF_PUBLIC) )
  342.                         {
  343.                           memcpy(SerRead,SerWrite,sizeof(struct IOExtSer));
  344.                           HandleIt();
  345.                           FreeMem(SerRead,sizeof(struct IOExtSer));
  346.                         }
  347.                         CloseDevice((struct IORequest *)SerWrite);
  348.                       } else puts("Can't open device!");
  349.                       DeleteExtIO((struct IORequest*)SerWrite);
  350.                     }
  351.                     DeletePort(SerPort);
  352.                   }
  353.                   CloseDevice((struct IORequest*)ConWrite);
  354.                 } else puts("cant open console device!");
  355.                 DeleteExtIO((struct IORequest*)ConRead);
  356.               }
  357.               DeleteExtIO((struct IORequest*)ConWrite);
  358.             }
  359.             DeletePort(ConWPort);
  360.           }
  361.           DeletePort(ConRPort);
  362.         }
  363.  
  364.         CloseWindow(Win);
  365.       }
  366.  
  367.  
  368.       UnlockPubScreen(NULL,Scr);
  369.     }
  370.     CloseLibs();
  371.   }
  372. }